package com.thread.demo.deadLock;

/**
 * 解释:线程thread1进入lock1后开始等待3000毫秒，此时线程thread2进入lock2锁后开始等待3000毫秒
 *     3000毫秒过后，thread1遇到lock2锁要等释放此时占用着lock1锁，而thread占用着lock2锁要等lock1锁释放
 *     此时出现两个线程死锁
 * 图形解释：进入某个锁可想象成进入一件屋子，释放锁就从屋里出来
 *
 * -------------------         -------------------
 * | A: B出来我再出去  |        | 去出再我来出A: B   |
 * -------------------         -------------------
 */
public class DeadThread1 implements Runnable {
    public String username;
    public Object lock1 = new Object();
    public Object lock2 = new Object();

    public void setFlag(String username) {
        this.username = username;
    }

    @Override
    public void run() {
        if (username.equals("a")) {
            synchronized (lock1) {
                try {
                    System.out.println("进入lock1,用户名:" + username);
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock2) {
                    System.out.println("执行顺序: lock1 -> lock2");
                }
            }
        }
        if (username.equals("b")) {
            synchronized (lock2) {
                System.out.println("进入lock2,用户名:" + username);
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock1) {
                    System.out.println("执行顺序: lock2 -> lock1");
                }
            }

        }

    }

    public static void main(String[] args) throws InterruptedException {

        DeadThread1 t1 = new DeadThread1();
        t1.setFlag("a");

        Thread thread1 = new Thread(t1);
        thread1.start();

        Thread.sleep(100);

        t1.setFlag("b");
        Thread thread2 = new Thread(t1);
        thread2.start();

    }
}
